package com.auditlog.sql.parser;

import cn.hutool.core.map.WeakConcurrentMap;
import com.auditlog.datasource.db.SqlType;
import com.auditlog.sql.factory.SqlRunnerFactory;
import com.auditlog.sql.factory.SqlRunnerFactoryRegistry;
import com.auditlog.datasource.struct.SqlMeta;
import com.auditlog.util.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.Statements;

import java.util.List;
import java.util.Map;

@Slf4j
public class CachedSqlParser {

    private static final Map<String, SqlMeta> SQL_META_MAP = new WeakConcurrentMap<>();

    public static SqlMeta parse(String sql) {
        return CollectionUtils.computeIfAbsent(SQL_META_MAP, sql, v -> {
            List<Statement> statementList;
            SqlMeta sqlMeta = new SqlMeta();
            try {
                Statements statements = CCJSqlParserUtil.parseStatements(sql);
                statementList = statements.getStatements();
                sqlMeta.setStatements(statementList);
                for (Statement s : statementList) {
                    SqlRunnerFactory sqlRunnerFactory = SqlRunnerFactoryRegistry.getInstance().support(s);
                    if (sqlRunnerFactory == null) {
                        log.warn("不支持的sql:{}", sql);
                    }
                    SqlType sqlType = sqlRunnerFactory.sqlType();
                    sqlMeta.addSqlType(sqlType);
                }
            } catch (JSQLParserException e) {
                log.error("sql解析出现异常:{},", sql, e);
                sqlMeta.setSqlType(SqlType.EXCEPTION);
            }
            return sqlMeta;
        });
    }
}
